<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <script src="vue.js"></script>
    <title>Title</title>
</head>
<body >
    <div id="app">
        <br>
        <div style="color: #ff0000">文本绑定到数据 {{}}  用v-once可以执行一次性地插值，如果数据改变了，不会更新dom</div>
        <div id="div-1" v-once>
            {{message}}
        </div>

        <br>
        <div style="color: #ff0000">标签绑定到数据 v-bind</div>
        <div id="app-2">
            <span v-bind:title="message2">
                鼠标停留几秒钟看动态数据提示
            </span>
        </div>

        <br>
        <div style="color: #ff0000">DOM结构绑定数据 v-if</div>
        <div>
            <p v-if="seen">现在你看到我了</p>
        </div>

        <br>
        <div style="color: #ff0000">循环输出 v-for</div>
        <div>
            <ol>
                <li v-for="todo in todos">
                    {{todo.text}}
                </li>
            </ol>
        </div>

        <br>
        <div style="color: #ff0000">v-on处理监听事件</div>
        <div>
            <p>{{message}}</p>
            <button v-on:click="reverseMessage">逆转消息</button>
        </div>

        <br>
        <div style="color: #ff0000">v-model实现表单输入和应用状态双向绑定</div>
        <div>
            <p>{{message}}</p>
            <input v-model="message">
        </div>

        <br>
        <div style="color: #ff0000">组件components的使用，以及props组件传值</div>
        <todo-item
            v-for="item in groceryList"
            v-bind:todo="item"
            v-bind:key ="item.key"></todo-item>

        <br>
        <div style="color: #ff0000">用v-html 输出真正的html</div>
        <div v-html="rawHtml"></div>

        <br>
        <div style="color: #ff0000">v-bind 用于在Html属性中使用</div>
        <div v-bind:id="dyid">动态生成的id</div>
        <div v-bind:disable="isButtonDisabled">控制Boolean值</div>

        <br>
        <div style="color: #ff0000">Js表达式计算，支持表达式</div>
        <div>
            <div>{{number + 1}}</div>
            <div>{{ok?'Yes':'No'}}</div>
            <div>{{message.split('').reverse().join('')}}</div>
            <div v-bind:id="'list' + id">动态计算id</div>
        </div>
        <div style="color: #ff0000">Js表达式计算，不支持语句</div>
        <div>
            <!--<div>{{var a = 1}}</div>
            <div>{{if(ok) {return message}}</div>-->
        </div>

        <br>
        <div style="color: #ff0000">过滤器filters应用与mustache和v-bind中</div>
        <div>{{messsage3 | capitalize}}</div>
        <div v-bind:id="id | formatId">过滤器计算id</div>

        <br>
        <div style="color: #ff0000">计算属性</div>
        <div>
            <p>Original message:"{{message}}"</p>
            <p>Computed reversed message:"{{reversedMessage}}"</p>
        </div>
        <br>
        <div style="color: #ff0000">计算属性setter\getter</div>
        <div>
            <p>first Name:{{firstName}}</p>
            <p>last Name:{{lastName}}</p>
            <p>full Name:{{fullName}}</p>
        </div>

        <br>
        <div style="color: #ff0000">绑定HTML CLass</div>
        <div v-bind:class="{active:isActive}">对象语法</div>
        <div style="color: #ff0000">多个class</div>
        <div class="static" v-bind:class="{active:isActive, 'text-danger': hasError}"></div>
        <div style="color: #ff0000">绑定对象</div>
        <div v-bind:class="classObject"></div>

        <br>
        <div style="color: #ff0000">绑定内联样式</div>
        <div v-bind:style="{color:activeColor, fontSize:fontSize + 'px'}"></div>

        <br>
        <div style="color: #ff0000">v-if的使用</div>
        <div v-if="ok">根据OK是否为true来显示</div>
        <div v-else>v-else的使用 OK为false则显示</div>
        <div style="color: #ff0000">v-if与tmplate的使用</div>
        <template v-if="ok">
            <p>使用template包装多个元素</p>
            <p>根据OK是否为true来显示</p>
        </template>
        <template v-else>
            <p>使用template包装多个元素</p>
            <p>OK为false则显示</p>
        </template>
        <div style="color: #ff0000">v-if v-else-if v-else的使用</div>
        <div v-if="type==='A'">A</div>
        <div v-else-if="type==='B'">B</div>
        <div v-else>其他</div>
        <div style="color: #ff0000">用key管理已有元素，复用；不想复用，通过增加key的方式</div>
        <template v-if="ok">
            <label>Username</label>
            <input placeholder="Enter your name" key="name">
        </template>
        <template v-else>
            <label>Email</label>
            <input placeholder="Enter your Email" key="email">
        </template>

        <br>
        <div style="color: #ff0000">v-show的使用</div>
        <p v-show="ok">不管ok是否为true总是渲染，如果为false,改变css样式, dispaly:nono</p>
        <p>总体来说，v-if:切换开销大；v-show：初始开销大。多次切换用v-show,不需要切换用v-if</p>

        <br>
        <div style="color: #ff0000">v-for的使用</div>
        <ul>
           <li v-for="(item, index) in items">
               {{'序号:' + index + ',message:' + item.message}}
           </li>
        </ul>
        <div style="color: #ff0000">v-for与template的使用</div>
        <ul>
            <template v-for="(item, index) in items">
                <li>{{'序号:' + index}}</li>
                <li>{{'message:' + item.message}}</li>
            </template>
        </ul>
        <div style="color: #ff0000">v-for通过一个对象的属性来迭代</div>
        <ul>
            <li v-for="(value, key, index) in object">
                {{index}}:{{key}}:{{value}}
            </li>
        </ul>
        <div style="color: #ff0000">v-for整数迭代</div>
        <div>
            <span v-for="n in 10">{{n}}</span>
        </div>
        <div style="color: #ff0000">v-for v-if的优先级</div>
        <li v-for="todo in todos" v-if="todo.isComplate">
            <span>{{todo.text + '-' + todo.isComplate}}</span>
        </li>
        <div style="color: #ff0000">如果先有条件跳过循环，则v-if包装元素（或template）</div>
        <template v-if="ok">
            <li v-for="todo in todos">
                <span>{{todo.text + '-' + todo.isComplate}}</span>
            </li>
        </template>

        <br>
        <div style="color: #ff0000">显示过滤、排序结果</div>
        <div style="color: #ff0000">通过计算属性实现</div>
        <li v-for="n in evenNumbers">{{n}}</li>
        <div style="color: #ff0000">通过方法实现</div>
        <li v-for="n in even()">{{n}}</li>

        <br>
        <div style="color: #ff0000">监听事件</div>
        <div>
            <button v-on:click="counter += 1">增加1</button>
            <p>这个按钮被点击了{{counter}}</p>
        </div>
        <div>
            <button v-on:click="greet">Greet</button>
        </div>
        <div>
            <button v-on:click="warn('evnetMessage', $event)">原生dom事件</button>
        </div>

        <br>
        <div style="color: #ff0000">事件修饰符</div>
        <div>
            <h2>V-on.stop</h2>
            <div @click="div_click">
                <button type="button" @click.stop="stop_click">StopPropagation</button>
            </div>
        </div>
        <div>
            <h2>v-on.prevent</h2>
            <form @submit.prevent="from_submit">
                <button type="submit">Submit</button>
            </form>
        </div>
        <div>
            <h2>v-on.self</h2>
            <div @click.self="div_click" style="background: #ff00ff">
                <button type="submit" @click="self_click">self_click</button>
            </div>
        </div>

        <div>
            <h2>v-on.once</h2>
            <button @click.once="once_click">once_click</button>
        </div>
        <div>
            <h2>键值修饰符</h2>
            <input type="text" @keyup.enter="enter_click" placeholder="监听回车键"/>
        </div>
        <br>
        <div @click.capture="div1">
            <div @click.capture="div2">
                <div @click="div3">
                    <div @click="div4">v-on.capture</div>
                </div>
            </div>
        </div>

        <br>
        <div style="color: #ff0000">v-model</div>
        <input v-model="message" placeholder="edit me">
        <p>Message is:{{message}}</p>

        <div style="color: #ff0000">单个勾选框</div>
        <input type="checkbox" id="checkbox" v-model="checked">
        <label for="checkbox">{{checked}}</label>

        <div style="color: #ff0000">多个勾选框</div>
        <input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
        <label for="jack">Jack</label>
        <input type="checkbox" id="john" value="John" v-model="checkedNames">
        <label for="john">John</label>
        <input type="checkbox" id="mike" value="Mike" v-model="checkedNames">
        <label for="mike">Mike</label>
        <span>checked names:{{checkedNames}}</span>

        <br>
        <div style="color: #ff0000">单选按钮</div>
        <input type="radio" id="One" value="One" v-model="picked">
        <label for="One">One</label>
        <br>
        <input type="radio" id="Two" value="Two" v-model="picked">
        <label for="Two">Two</label>
        <br>
        <span>Picked:{{picked}}</span>

        <div style="color: #ff0000">单选列表</div>
        <div>
            <select v-model="selected">
                <option disabled value="">请选择</option>
                <option>A</option>
                <option>B</option>
                <option>C</option>
            </select>
            <span>Selected:{{selected}}</span>
        </div>

        <div style="color: #ff0000">多选列表</div>
        <div>
            <select v-model="selectedArr" multiple style="width:50px">
                <option>A</option>
                <option>B</option>
                <option>C</option>
            </select>
            <span>Selected:{{selectedArr}}</span>
        </div>

        <div style="color: #ff0000">绑定Value</div>
        <input type="radio" v-model="pick" v-bind:value="message">
        <span>{{pick}}</span>

        <my-component></my-component>
        <child></child>
        <table>
            <tr is="child"></tr>
        </table>

        <br>
        <div id="example-2">
            <div style="color: #ff0000">共用data2对象引起的问题</div>
            <simple-counter></simple-counter>
            <simple-counter></simple-counter>
            <simple-counter></simple-counter>
        </div>

        <br>
        <div style="color: #ff0000">组件传值</div>
        <child2 my-msg='通过prop从父控件向子控件传值'></child2>
        <div style="color: #ff0000">动态Prop</div>
        <div>
            <input v-model="parentMsg">
            <br>
            <child2 v-bind:my-msg="parentMsg" a="gg"></child2>
        </div>

        <br>
        <div style="color: #ff0000">自定义事件</div>
        <div>
            <p>{{total}}</p>
            <button-counter v-on:increment="incrementTotal"></button-counter>
            <button-counter v-on:click.native="nativeMethod" v-on:increment="incrementTotal"></button-counter>
        </div>

        <br>
        <div style="color: #ff0000">.sync修饰符{{message}}</div>
        <comp :foo.sync="message" ></comp>

    </div>
    <script type="text/javascript">
        Vue.component('comp', {
            template:'<span v-on:click="updateMessage()">修改父组件变量{{foo}}</span>',
            props: ['foo'],
            methods: {
                updateMessage: function() {
                    this.$emit('update:foo', '新的Message')
                }
            }
        })

        Vue.component('button-counter',{
            template:'<button v-on:click="incrementCounter">{{counter}}</button>',
            data:function() {
                return {
                    counter: 0
                }
            },
            methods: {
                incrementCounter: function() {
                    this.counter += 1
                    this.$emit('increment')
                }
            }
        })

        Vue.component('child2', {
            //声明props
            props:['myMsg'],
            //就像data一样，prop可以用在模板内
            //同样可以在vm实例中像this.message这样使用
            template:'<span>{{myMsg}}</span>',
            created:function() {
            }
        })
        var data2 = { counter: 0 }
        Vue.component('simple-counter', {
            template: '<button v-on:click="counter += 1">{{ counter }}</button>',
            // 技术上 data 的确是一个函数了，因此 Vue 不会警告，
            // 但是我们返回给每个组件的实例的却引用了同一个data对象
            data: function () {
                return data2
                //return { counter: 0 }
            }
        })
        var data = {a: 1}
        var child = {template:'<div>局部注册的template</div>'}
        Vue.component('my-component',{
            template:'<div>A custom component!</div>'
        })
        var app = new Vue({
            el:'#app',
            filters: {
                capitalize:function(value) {
                    if (!value) return ''
                    value = value.toString()
                    return value.charAt(0).toUpperCase() + value.slice(1)
                },
                formatId:function(value) {
                    return 'format' + value
                }
            },
            data:{
                total: 0,
                parentMsg:'',
                pick:'',
                selectedArr:[],
                selected:'',
                picked: '',
                checkedNames:[],
                checked: false,
                name: 'vue.js',
                counter:0,
                numbers: [1,2,3,4,5],
                object: {
                    firstName:'tang',
                    lastName:'Doe',
                    age:30
                },
                items: [
                    {message: 'Foo'},
                    {message: 'Bar'}
                ],
                message:'Hellow Vue!',
                message2:'页面加载于' + new Date(),
                messsage3: 'abc',
                seen: true,
                todos: [
                    {text: '学习Js', isComplate: true},
                    {text: '学习Vue', isComplate: false},
                    {text: '学习项目', isComplate: true}
                ],
                groceryList: [
                    {id:0, text:'素菜'},
                    {id:1, text:'荤菜'},
                    {id:2, text:'蛋糕'},
                ],
                data: data,
                rawHtml:'background:#fff000',
                dyid: 'dyscid',
                isButtonDisabled: true,
                number: 1,
                ok: true,
                message: 'Hello Word',
                id: 24,
                firstName: 'tang',
                lastName: 'josan',
                isActive: true,
                hasError: true,
                classObject: {
                  active:true,
                  'text-danger': false
                },
                activeColor: 'red',
                fontSize: 30,
                ok: true,
                type: 'A'
            },
            methods:{
                nativeMethod: function() {
                    console.log("gg")
                },
                incrementTotal:function() {
                    this.total += 1
                },
                div1:function() {
                    console.log("div1")
                },
                div2:function() {
                    console.log("div2")
                },
                div3:function() {
                    console.log("div3")
                },
                div4:function() {
                    console.log("div4")
                },
                enter_click: function() {
                    console.log("enter_click")
                },
                once_click: function() {
                    console.log("once_click")
                },
                self_click: function() {
                    console.log("self_click")
                },
                from_submit: function() {
                    console.log("from_submit")
                    //alert("from_submit")
                },
                div_click: function() {
                  console.log("div click")
                },
                stop_click: function(){
                    console.log("stop_click")
                },
                warn: function(message, event) {
                    if (event) event.preventDefault()
                    alert(message)
                },
                greet:function(event) {
                  alert('Hello' + this.name + '!')
                    if (event) {
                      alert(event.target.tagName)
                    }
                },
                reverseMessage: function() {
                    this.message = this.message.split('').reverse().join('')
                },
                even: function() {
                    return this.numbers.filter(function(number){
                        return number % 2 === 0
                    })
                }
            },
            computed: {
                //getter
                reversedMessage: function() {
                    return this.message.split('').reverse().join('')
                },
                //setter
                fullName: {
                    get: function() {
                        return this.firstName + '-' + this.lastName
                    },
                    set: function(newValue) {
                        var name = newValue.split(' ')
                        this.firstName = name[0]
                        this.lastName = name[1]
                    }
                },
                evenNumbers:function() {
                    return this.numbers.filter(function(number){
                        return number % 2 === 0
                    })
                }
            },
            created() {
                // 在实例被创建之后调用
                console.log('created 在实例被创建之后调用')
                this.todos.push({text: '尜尜'})
            },
            mounted() {
                // 挂载到Dom上时调用
                console.log('mounted 挂载到Dom上时调用')
            },
            updated() {
                // 更新视图时调用
                console.log('updated 更新视图时调用')
            },
            destroyed() {
                // 销毁视图时调用
                console.log('destroyed 销毁视图时调用')
            },
            components:{
                'todo-item': {
                    props:['todo'],
                    template:'<li>{{todo.text}}</li>'
                },
                'child': child
            }
        })

        //每个vue实例都会代理其data对象里所有的属性
        //设置属性会影响到原始属性
        //反之亦然
        //如果实例创建之后创建的的属性，不会更新视图效果
        app.$data.data.a = 2
        console.log(data.a)

        //用前缀$去调用暴露出来的一些属性与方法，注意，不要用箭头函数，否则this不是指当前Vue对象
        console.log(app.$el === document.getElementById('app'))
        app.$watch('seen', function(newVal, oldVal) {
            console.log(newVal + '-' + oldVal)
        })

    </script>
</body>
</html>

